package cn.zhxu.pack;

public class ColorRGB {

    private int r;
    private int g;
    private int b;

    public ColorRGB() {
    }

    public ColorRGB(int r, int g, int b) {
        assert 0 <= r && r <= 255;
        assert 0 <= g && g <= 255;
        assert 0 <= b && b <= 255;
        this.r = r;
        this.g = g;
        this.b = b;
    }

    public static ColorRGB parse(String color) {
        if (color.charAt(0) == '#') {
            color = color.substring(1);
        }
        int len = color.length();
        if (len == 6 || len == 3) {
            String rs = color.substring(0, len / 3);
            String gs = color.substring(len / 3, 2 * len / 3);
            String bs = color.substring(2 * len / 3, 3 * len / 3);
            try {
                int r = Integer.parseInt(rs, 16);
                int g = Integer.parseInt(gs, 16);
                int b = Integer.parseInt(bs, 16);
                if (len == 3) {
                    r *= 16;
                    g *= 16;
                    b *= 16;
                }
                return new ColorRGB(r, g, b);
            } catch (NumberFormatException e) {
                throw new ColorException("Invalid color: " + color, e);
            }
        }
        throw new ColorException("Invalid color: " + color);
    }

    public int max() {
        return Math.max(r, Math.max(g, b));
    }

    public int min() {
        return Math.min(r, Math.min(g, b));
    }

    public ColorHSB toHSB() {
        int max = max();
        int min = min();
        float hsbB = max / 255.0f;
        float hsbS = max == 0 ? 0 : (max - min) / (float) max;
        float hsbH = 0;
        if (max == r && g >= b) {
            hsbH = (g - b) * 60f / (max - min) + 0;
        } else if (max == r) {
            hsbH = (g - b) * 60f / (max - min) + 360;
        } else if (max == g) {
            hsbH = (b - r) * 60f / (max - min) + 120;
        } else if (max == b) {
            hsbH = (r - g) * 60f / (max - min) + 240;
        }
        return new ColorHSB(hsbH, hsbS, hsbB);
    }

    @Override
    public String toString() {
        String rs = Integer.toString(r, 16);
        String gs = Integer.toString(g, 16);
        String bs = Integer.toString(b, 16);
        if (rs.length() < 2) {
            rs = "0" + rs;
        }
        if (gs.length() < 2) {
            gs = "0" + gs;
        }
        if (bs.length() < 2) {
            bs = "0" + bs;
        }
        return "#" + rs + gs + bs;
    }

    public int getR() {
        return r;
    }

    public void setR(int r) {
        assert 0 <= r && r <= 255;
        this.r = r;
    }

    public int getG() {
        return g;
    }

    public void setG(int g) {
        assert 0 <= g && g <= 255;
        this.g = g;
    }

    public int getB() {
        return b;
    }

    public void setB(int b) {
        assert 0 <= b && b <= 255;
        this.b = b;
    }

}
